home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / polyOp.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  7KB  |  256 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/StringDefs.h>
  17. #include <X11/cursorfont.h>
  18. #include "xpaint.h"
  19. #include "misc.h"
  20. #include "Paint.h"
  21.  
  22. #define    FILL        0x2
  23. #define    POLY        0x1
  24. #define IsPoly(x)    (x & POLY)
  25. #define    IsFill(x)    (x & FILL)
  26.  
  27. #define MAXP    100
  28.  
  29. typedef struct {
  30.     int    flag;
  31.     int    startX, startY, endX, endY, button;
  32.     int    drawn, first, tracking, go;
  33.     int    npoints;
  34.     XPoint    points[MAXP+1];
  35.     XPoint    real[MAXP+1];
  36.     /*
  37.     **  Borrowed from my info structure.
  38.     */
  39.     GC    fgc, lgc, gcx;
  40.     Pixmap    pixmap;
  41.     Widget    widget;
  42.     Boolean    isFat;
  43. } LocalInfo;
  44.  
  45. static void     finish(Widget w, LocalInfo *l, Boolean flag)
  46. {
  47.     if (!l->tracking)
  48.         return;
  49.  
  50.     l->tracking = False;
  51.  
  52.     if (l->drawn)
  53.         XDrawLines(XtDisplay(w), XtWindow(w), l->gcx,
  54.             l->points, l->npoints, CoordModeOrigin);
  55.     if (flag && l->drawn)
  56.         XDrawLine(XtDisplay(w), XtWindow(w), l->gcx,
  57.             l->points[l->npoints-1].x,
  58.             l->points[l->npoints-1].y,
  59.             l->endX, l->endY);
  60.  
  61.     if (IsFill(l->flag)) {
  62.         if (!l->isFat)
  63.             XFillPolygon(XtDisplay(w), XtWindow(w), l->fgc,
  64.                 l->real, l->npoints, Complex, CoordModeOrigin);
  65.         XFillPolygon(XtDisplay(w),  l->pixmap, l->fgc, 
  66.                 l->real, l->npoints, Complex,CoordModeOrigin);
  67.     }
  68.  
  69.     if (IsPoly(l->flag)) {
  70.         l->real[l->npoints].x = l->real[0].x;
  71.         l->real[l->npoints].y = l->real[0].y;
  72.         l->npoints++;
  73.     }
  74.     if (!l->isFat)
  75.         XDrawLines(XtDisplay(w), XtWindow(w), l->lgc,
  76.             l->real, l->npoints, CoordModeOrigin);
  77.     XDrawLines(XtDisplay(w),  l->pixmap, l->lgc, 
  78.             l->real, l->npoints, CoordModeOrigin);
  79.  
  80.     PwUpdate(w, NULL, False);
  81. }
  82.  
  83. static void    press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
  84. {
  85.     if (!l->tracking && event->button == Button1) {
  86.         l->endX = l->startX = event->x;
  87.         l->endY = l->startY = event->y;
  88.  
  89.         l->button = event->button;
  90.  
  91.         l->npoints = 0;
  92.  
  93.         l->points[l->npoints].x = event->x;
  94.         l->points[l->npoints].y = event->y;
  95.         l->real[l->npoints].x = info->x;
  96.         l->real[l->npoints].y = info->y;
  97.         l->npoints++;
  98.  
  99.         l->drawn = False;
  100.         l->tracking = True;
  101.         l->first = True;
  102.  
  103.         l->isFat = info->isFat;
  104.         l->fgc   = info->second_gc;
  105.         l->lgc   = info->first_gc;
  106.     } else if (event->button == Button2 && l->tracking) {
  107.         finish(w, l, True);
  108.         return;
  109.     }
  110.  
  111.     if (l->first && info->surface == opPixmap) {
  112.         UndoStartPoint(w, info, info->x, info->y);
  113.         l->pixmap = info->drawable;
  114.         l->widget = w;
  115.     }
  116. }
  117.  
  118. static void    release(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
  119. {
  120.     if (l->npoints == MAXP - 1)
  121.         return;
  122.  
  123.     if (info->surface == opWindow) {
  124.         if (!l->first) {
  125.             l->endX = l->points[l->npoints].x = event->x;
  126.             l->endY = l->points[l->npoints].y = event->y;
  127.             l->startX = event->x;
  128.             l->startY = event->y;
  129.         }
  130.         return;
  131.     }
  132.     if (l->first) {
  133.         l->first = False;
  134.         return;
  135.     }
  136.  
  137.     /*
  138.     **  else on the pixmap.
  139.     */
  140.     l->real[l->npoints].x   = info->x;
  141.     l->real[l->npoints].y   = info->y;
  142.     l->npoints++;
  143.  
  144.     UndoGrow(w, info->x, info->y);
  145. }
  146.  
  147. static void    motion(Widget w, LocalInfo *l, XMotionEvent *event, OpInfo *info)
  148. {
  149.     /*
  150.     **  Haven't done the first button press
  151.     */
  152.     if (!l->tracking || l->first)
  153.         return;
  154.  
  155.     if (l->drawn) 
  156.         XDrawLine(XtDisplay(w), info->drawable, l->gcx,
  157.                 l->startX, l->startY, l->endX, l->endY);
  158.  
  159.     l->endX = event->x;
  160.     l->endY = event->y;
  161.  
  162.     if (l->drawn = (l->startX != l->endX && l->startY != l->endY)) 
  163.         XDrawLine(XtDisplay(w), info->drawable, l->gcx,
  164.                 l->startX, l->startY, l->endX, l->endY);
  165. }
  166.  
  167.  
  168. /*
  169. **  Those public functions
  170. */
  171. void *PolyAdd(Widget w)
  172. {
  173.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  174.  
  175.     l->flag = POLY;
  176.     l->drawn = False;
  177.     l->first = True;
  178.     l->tracking = False;
  179.     l->gcx = GetGCX(w);
  180.  
  181.     XtVaSetValues(w, XtNcompress, True, NULL);
  182.  
  183.     OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  184.     OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
  185.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  186.     SetCrossHairCursor(w);
  187.  
  188.     return l;
  189. }
  190. void PolyRemove(Widget w, LocalInfo *l)
  191. {
  192.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  193.     OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
  194.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  195.  
  196.     finish(w, l, True);
  197.  
  198.     XtFree((XtPointer)l);
  199. }
  200. void *FPolyAdd(Widget w)
  201. {
  202.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  203.  
  204.     l->flag = POLY|FILL;
  205.     l->drawn = False;
  206.     l->first = True;
  207.     l->tracking = False;
  208.     l->gcx = GetGCX(w);
  209.  
  210.     XtVaSetValues(w, XtNcompress, True, NULL);
  211.  
  212.     OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  213.     OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
  214.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  215.     SetCrossHairCursor(w);
  216.  
  217.     return l;
  218. }
  219. void FPolyRemove(Widget w, LocalInfo *l)
  220. {
  221.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  222.     OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
  223.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  224.  
  225.     finish(w, l, True);
  226.     XtFree((XtPointer)l);
  227. }
  228. void *CLineAdd(Widget w)
  229. {
  230.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  231.  
  232.     l->flag = 0;
  233.     l->drawn = False;
  234.     l->first = True;
  235.     l->tracking = False;
  236.     l->gcx = GetGCX(w);
  237.  
  238.     XtVaSetValues(w, XtNcompress, True, NULL);
  239.  
  240.     OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  241.     OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
  242.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  243.     SetCrossHairCursor(w);
  244.  
  245.     return l;
  246. }
  247. void CLineRemove(Widget w, LocalInfo *l)
  248. {
  249.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  250.     OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
  251.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  252.  
  253.     finish(w, l, True);
  254.     XtFree((XtPointer)l);
  255. }
  256.